package com.xyrl.common.util;

import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.connection.DataType;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * 缓存数据库操作
 */
@Slf4j
public class RedisUtil {
    /**
     * redis template
     */
    private static RedisTemplate<String, Object> redisTemplate;

    /**
     * 初始赋值
     *
     * @param reids
     */
    public void initRedisTemplate(RedisTemplate<String, Object> reids) {
        redisTemplate = reids;
    }

    /**
     * 判断key 是否存在
     *
     * @param key
     * @return
     */
    public static boolean hasKey(String key) {
        return redisTemplate.hasKey(key);
    }

    /**
     * 取得 值类型
     *
     * @param key
     * @return
     */
    public static DataType valueType(String key) {
        return redisTemplate.type(key);
    }

    /**
     * 删除key
     *
     * @param key
     * @return
     */
    public static void delKey(String key) {
        redisTemplate.delete(key);
    }

    /**
     * 设置key 的过期时间 单位为秒
     *
     * @param key  redis key
     * @param time 过期时间
     */
    public static boolean setExpireTime(String key, Long time) {
        return setExpireTime(key, time, TimeUnit.SECONDS);
    }

    /**
     * 设置key 的过期时间
     *
     * @param key      redis key
     * @param time     过期时间
     * @param timeUnit 时间单位
     */
    public static boolean setExpireTime(String key, Long time, TimeUnit timeUnit) {
        return redisTemplate.expire(key, time, timeUnit);
    }


    /**
     * 获得key 的失效剩余时间
     *
     * @param key
     * @return
     */
    public static long getExpireTime(String key) {
        return redisTemplate.getExpire(key);
    }


    public static void setData(String key, Object value) {
        try {
            redisTemplate.opsForValue().set(key, value);
        } finally {
        }
    }

    /**
     * 设置redis 值
     *
     * @param key        key
     * @param value      对应值
     * @param expireTime 过期时间
     * @param timeUnit   单位
     */
    public static void setData(String key, Object value, long expireTime, TimeUnit timeUnit) {
        try {
            redisTemplate.opsForValue().set(key, value, expireTime, timeUnit);
        } finally {
        }
    }


    /**
     * 根据key获取记录
     *
     * @param key String
     * @return 值
     */
    public static String getData(String key) {
        String value = String.valueOf(redisTemplate.opsForValue().get(key));
        return value;
    }

    /**
     * 根据key获取记录
     *
     * @param key String
     * @return 值
     */
    public static <T> T getData(String key, Class<T> clazz) {
        try {
            return (T) redisTemplate.opsForValue().get(key);
        } catch (Exception e) {
            log.error("调用RedisUtil.getObj 方法转弄异常：", e);
            return null;
        }
    }


    /**
     * 保存set数据
     *
     * @param key  key值
     * @param data 数据
     */
    public static long setSet(String key, String... data) {
        try {
            return redisTemplate.opsForSet().add(key, data);
        } finally {
        }
    }


    /**
     * 获取set数据
     *
     * @param key key
     */
    public static Set<Object> getSet(String key) {
        Set<Object> set = null;
        try {
            if (ObjectUtil.isNotEmpty(key)) {
                set = redisTemplate.opsForSet().members(key);
            }
        } finally {
        }
        return set;
    }

    /**
     * 添加有序集合
     *
     * @param key
     * @param value
     * @param scoure
     */
    public static boolean setSortSet(String key, String value, Long scoure) {
        try {
            redisTemplate.opsForZSet().add(key, value, scoure);
            return true;
        } catch (Exception e) {
            log.error("", e);
            return false;
        }
    }


    /**
     * 删除有序队列值
     *
     * @param key
     * @param value
     */
    public static boolean delSortSet(String key, Object value) {
        try {
            redisTemplate.opsForZSet().remove(key, value);
            return true;
        } catch (Exception e) {
            log.error("", e);
            return false;
        }
    }

    /**
     * 取得满足条件的set集合
     *
     * @param key key
     * @param min 最小值
     * @param max 最大值
     * @return
     */
    public static Set<Object> getSortSet(String key, long min, long max) {
        Set<Object> set = redisTemplate.opsForZSet().rangeByScore(key, min, max);
        return set;
    }

    /**
     * 删除集合数据
     *
     * @param key  key值
     * @param data 数据
     */
    public static void delSet(String key, String... data) {
        try {
            if (ObjectUtil.isNotEmpty(data)) {
                redisTemplate.opsForSet().remove(key, data);
            }
        } finally {
        }
    }


    /**
     * 保存数据至list中
     *
     * @param key
     * @param value
     * @return
     */
    public static long setLists(String key, String... value) {
        try {
            return redisTemplate.opsForList().leftPushAll(key, value);
        } finally {
        }
    }

    /**
     * 取得所有例表
     *
     * @param key
     * @return
     */
    public static List<Object> getList(String key) {
        return getList(key, 0, -1);
    }

    /**
     * 取得list例表
     *
     * @param key   存放key
     * @param start 开始值
     * @param end   结束值
     * @return
     */
    public static List<Object> getList(String key, int start, int end) {
        try {
            return redisTemplate.opsForList().range(key, start, end);
        } finally {

        }
    }


    /**
     * 设置map 值
     *
     * @param key
     * @param mapKey
     * @param mapValue
     * @return
     */
    public static void setMap(String key, String mapKey, String mapValue) {
//        return redisTemplate.opsForHash().putIfAbsent(key, mapKey, mapValue);
        redisTemplate.opsForHash().put(key, mapKey, mapValue);
    }

    /**
     * 批量设置maps 值合
     *
     * @param key
     * @param maps
     */
    public static void setMap(String key, Map<Object, Object> maps) {
        redisTemplate.opsForHash().putAll(key, maps);
    }

    /**
     * 批量设置maps 值合
     *
     * @param key
     * @param maps
     */
    public static void setMap(String key, Map<Object, Object> maps, long time, TimeUnit timeUnit) {
        redisTemplate.opsForHash().putAll(key, maps);
        redisTemplate.expire(key, time, timeUnit);
    }

    /**
     * 取得map 值
     *
     * @param key
     * @return
     */
    public static Map<Object, Object> getMap(String key) {
        return redisTemplate.opsForHash().entries(key);
    }
    /**
     * 取得map 值
     *
     * @param key
     * @return
     */
    public static Object getMap(String key,String mapKey) {
        //.entries(key).get(mapKey);
        return redisTemplate.opsForHash().get(key,mapKey);
    }

    public static List<Object> getMap(String key, Set<Object> mapKeys){
        return redisTemplate.opsForHash().multiGet(key,mapKeys);
    }
    /**
     * 取得map 值
     *
     * @param key
     * @return
     */
    public static boolean delMap(String key, String mapKey) {
        long t = redisTemplate.opsForHash().delete(key, mapKey);
        if (t > 0) {
            return true;
        }
        return false;
    }

    /**
     * 整形递减
     *
     * @param key 键
     * @return
     * @delta by 要减少几(小于0)
     */
    public static long longDecr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递减因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, -delta);
    }

    /**
     * 整形递加
     *
     * @param key 键
     * @return
     * @delta by 要加几(小于0)
     */
    public static long longIncr(String key, long delta) {
        if (delta < 0) {
            throw new RuntimeException("递加因子必须大于0");
        }
        return redisTemplate.opsForValue().increment(key, delta);
    }


    public static void test() {
        Properties properties = redisTemplate.getRequiredConnectionFactory().getConnection().info();
        System.out.println(properties.keySet());
    }

    public static void main(String[] args) {

    }
}
